/**
 *	@brief	ポケギアラジオ BG描画
 *	@author	Miyuki Iwasawa
 *	@date	07.06.20
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "gflib/touchpanel.h"
#include "field/field_matrix.h"
#include "field/field_place_name.h"
#include "field/zonedata.h"
#include "application/app_tool.h"
#include "application/pokegear.h"
#include "msgdata/msg.naix"
#include "field/field_se.h"		// in FieldSePlayRequest();

#include "../pgear_sys.h"
#include "../pgear_frm.h"
#include "../pgear_act.h"
#include "pgradio_sys.h"
#include "pgradio_sub.h"
#include "pgradio_key.h"

#define __BGRADIO_BG_H_GLOBAL
#include "pgradio_bg.h"

#include "pgradio_gra.naix"
#include "msgdata/msg_pg_radio.h"

//===========================================================================
///プロトタイプ
//===========================================================================
static void pgradio_BGLInit(PGRADIO_SYS_WORK* wk);
static void pgradio_BGLRelease(PGRADIO_SYS_WORK* wk);
static void pgradio_2DResInit(PGRADIO_SYS_WORK* wk);
static void pgradio_2DResRelease(PGRADIO_SYS_WORK* wk);
static void pgradio_PalAnmWorkSet(PGRADIO_SYS_WORK* wk);
static void pgradio_BmpWinAdd(PGRADIO_SYS_WORK* wk);
static void pgradio_BmpWinDel(PGRADIO_SYS_WORK* wk);
static void pgradio_ActResInit(PGRADIO_SYS_WORK* wk);
static void pgradio_ActResRelease(PGRADIO_SYS_WORK* wk);
static void pgradio_MakeActor(PGRADIO_SYS_WORK* wk);
static void pgradio_DelActor(PGRADIO_SYS_WORK* wk);
static void pgradio_IniDraw(PGRADIO_SYS_WORK* wk);


//===========================================================================
///プログラムエリア
//===========================================================================
/**
 *	@brief	マップの初期化
 */
int PGRadio_AppInit(PGRADIO_SYS_WORK* wk)
{
	switch(wk->sub_seq){
	case 0:
		pgradio_BGLInit(wk);
		pgradio_2DResInit(wk);
		pgradio_BmpWinAdd(wk);
		pgradio_ActResInit(wk);
		//OBJ実体作成前にパレットアニメワークを登録
		pgradio_PalAnmWorkSet(wk);
		break;
	case 1:
		pgradio_MakeActor(wk);
		pgradio_IniDraw(wk);

		//アプリVBlank関数登録
		wk->sys->app_vfunc = PGRadioSub_VBlank;

		wk->sub_seq = 0;
		return TRUE;
	}
	++wk->sub_seq;
	return FALSE;
}

/**
 *	@brief	マップの開放
 */
int PGRadio_AppEnd(PGRADIO_SYS_WORK* wk)
{
	switch(wk->sub_seq){
	case 0:
		//番組が非選択 or プログラム終了期間中なら、フィールドBGMを復帰させる
		if(	PGRadioKey_GetChannelFromPos(wk,wk->x,wk->y,NULL) == RADIO_CHANNEL_NONE ||
			(wk->pRadioSys->program_end_f) ||
			(wk->pRadioSys->prog_id == RADIO_PROG_CM)){
			Snd_BgmFadeOut( 0, 4 );
		}else{
			wk->sub_seq = 2;
			break;
		}
		wk->sub_seq++;
		break;
	case 1:
		if(Snd_FadeCheck()){
			break;
		}
		Snd_BgmPlay(wk->sys->param->fld_bgm);
		// フィールド環境音の保存音をクリアする
		FieldSePlayRequest( );

		wk->sub_seq++;
		break;
	case 2:
		//アプリVBlank関数登録削除
		wk->sys->app_vfunc = NULL;

		pgradio_DelActor(wk);
		pgradio_ActResRelease(wk);
		pgradio_BmpWinDel(wk);
		pgradio_2DResRelease(wk);
		pgradio_BGLRelease(wk);
		wk->sub_seq = 0;
		return TRUE;
	}
	return FALSE;
}

#if 0
/**
 *	@brief	リストの選択
 */
int PGRadio_ListSelect(PGRADIO_SYS_WORK* wk)
{
	return PGRADIO_SEQ_LIST_SELECT;
}
#endif

/**
 *	@brief	ラジオのBGL初期化
 */
static void pgradio_BGLInit(PGRADIO_SYS_WORK* wk)
{
	int i;
	GF_BGL_INI* bgl = wk->sys->bgl;

	//メインのBGモードをtext,text,affineEx,affineExのMode5に変更
	{
		//GFルールでは直接呼ぶべきではないが、ポケギアでは特別に呼ぶ
		GX_SetGraphicsMode( GX_DISPMODE_GRAPHICS, GX_BGMODE_0,GX_BG0_AS_2D );
	}

	{	//BG0はフレームの占有領域なのでいじらないこと！
		GF_BGL_BGCNT_HEADER TextBgCntDat[] = {
		{	//MAIN BG1
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			1,0,0,FALSE},
		{	//MAIN BG2
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			2,0,0,FALSE},
		{	//MAIN BG3
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe000,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			3,0,0,FALSE},
		{	//SUB BG1
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			0,0,0,FALSE},
		{	//SUB BG2
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			1,0,0,FALSE},
		{	//SUB BG3
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe000,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			2,0,0,FALSE},
		};
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME1_M,&(TextBgCntDat[0]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME2_M,&(TextBgCntDat[1]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME3_M,&(TextBgCntDat[2]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME1_S,&(TextBgCntDat[3]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME2_S,&(TextBgCntDat[4]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME3_S,&(TextBgCntDat[5]),GF_BGL_MODE_TEXT,VISIBLE_OFF);

		for(i = 0;i < 3;i++){
			GF_BGL_ScrClear(wk->sys->bgl,GF_BGL_FRAME1_M+i);
			GF_BGL_ClearCharSet(GF_BGL_FRAME1_M+i,32,0,wk->heapID);
			GF_BGL_ScrClear(wk->sys->bgl,GF_BGL_FRAME1_S+i);
			GF_BGL_ClearCharSet(GF_BGL_FRAME1_S+i,32,0,wk->heapID);
		}
	}

}

/**
 *	@brief	ラジオBGL開放
 *
 */
static void pgradio_BGLRelease(PGRADIO_SYS_WORK* wk)
{
	PGFrame_LocalVramClear(wk->sys);
#if 0
	//ローカルパレット領域をクリア
	GF_BGL_ClearPaletteSet(GF_BGL_FRAME3_M,0x20*PGAPP_PALNUM_M,0 ,wk->heapID);
	GF_BGL_ClearPaletteSet(GF_BGL_FRAME3_S,0x20*PGAPP_PALNUM_S,0 ,wk->heapID);

	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME3_S);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME2_S);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME1_S);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME3_M);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME2_M);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME1_M);
#endif
}

/**
 *	@brief	ラジオのBGリソース初期化
 */
static void pgradio_2DResInit(PGRADIO_SYS_WORK* wk)
{
	ARCHANDLE* handle;
	int	arcID;

	//ここでタッチフォントも追加しておく
	FontProc_LoadFont( FONT_TOUCH, wk->heapID );

	arcID = ARC_PGRADIO_GRA;

	//アーカイブハンドル取得
	handle = ArchiveDataHandleOpen(arcID,wk->heapID);

	//キャラクタ転送
	APP_ArcFileVramLoad(wk->sys->bgl,wk->heapID,
		handle,arcID,NARC_pgradio_gra_rfrm001_ncgr+wk->skin,
		GF_BGL_FRAME2_M,0,0,0);
	APP_ArcFileVramLoad(wk->sys->bgl,wk->heapID,
		handle,arcID,NARC_pgradio_gra_rguide001_ncgr+wk->skin,
		GF_BGL_FRAME3_S,0,0,0);

	//スクリーン転送
	APP_ArcFileVramLoad(wk->sys->bgl,wk->heapID,
		handle,arcID,NARC_pgradio_gra_rfrm1001_nscr+wk->skin,
		GF_BGL_FRAME2_M,1,0x800,0);
	APP_ArcFileVramLoad(wk->sys->bgl,wk->heapID,
		handle,arcID,NARC_pgradio_gra_rfrm2001_nscr+wk->skin,
		GF_BGL_FRAME3_M,1,0x800,0);
	APP_ArcFileVramLoad(wk->sys->bgl,wk->heapID,
		handle,arcID,NARC_pgradio_gra_rguide001_nscr+wk->skin,
		GF_BGL_FRAME3_S,1,0x800,0);

	//スクリーンリソース取得
	wk->pSBufBg = ArcUtil_HDL_ScrnDataGet(handle,
			NARC_pgradio_gra_rfrm1001_nscr+wk->skin,FALSE,
			&wk->pSBg,wk->heapID);

	//ハンドル閉じる
	ArchiveDataHandleClose( handle );

	//スクリーン転送
	GF_BGL_LoadScreenV_Req(wk->sys->bgl,GF_BGL_FRAME2_M);
	GF_BGL_LoadScreenV_Req(wk->sys->bgl,GF_BGL_FRAME3_S);
}

/**
 *	@brief	ラジオのBGリソース開放
 */
static void pgradio_2DResRelease(PGRADIO_SYS_WORK* wk)
{
	sys_FreeMemoryEz(wk->pSBufBg);

	FontProc_UnloadFont( FONT_TOUCH );
}

/**
 *	@brief	パレットアニメワークセット
 */
static void pgradio_PalAnmWorkSet(PGRADIO_SYS_WORK* wk)
{
	u8	evy;
	int	arcID;
	ARCHANDLE* handle;

	//アーカイブハンドル取得
	arcID = ARC_PGRADIO_GRA;
	handle = ArchiveDataHandleOpen(arcID,wk->heapID);

	//パレットアニメワークに登録
	PaletteWorkSetEx_ArcHandle(wk->sys->palAnm,handle,
		NARC_pgradio_gra_rbgd001_nclr+wk->skin,wk->heapID,
		FADE_MAIN_BG,FADE_PAL_ONE_SIZE*PGAPP_PALNUM_M,16*PGAPP_PALIDX_M,16*PGAPP_PALIDX_M);
	PaletteWorkSetEx_ArcHandle(wk->sys->palAnm,handle,
		NARC_pgradio_gra_rbgu001_nclr+wk->skin,wk->heapID,
		FADE_SUB_BG,FADE_PAL_ONE_SIZE*PGAPP_PALNUM_S,16*PGAPP_PALIDX_S,16*PGAPP_PALIDX_S);

	//パレットアニメワークに登録
	PaletteWorkSetEx_ArcHandle(wk->sys->palAnm,handle,
		NARC_pgradio_gra_oam_radio_nclr,wk->heapID,
		FADE_MAIN_OBJ,FADE_PAL_ONE_SIZE*PGAPPOAM_PALNUM_M,16*PGAPPOAM_PALIDX_M,0);
	PaletteWorkSetEx_ArcHandle(wk->sys->palAnm,handle,
		NARC_pgradio_gra_oam_radio_nclr,wk->heapID,
		FADE_SUB_OBJ,FADE_PAL_ONE_SIZE*PGAPPOAM_PALNUM_S,16*PGAPPOAM_PALIDX_S,0);

	//ブラックアウト状態に変更しておく
	PaletteTrans_AutoSet(wk->sys->palAnm,TRUE);
	SoftFadePfd(wk->sys->palAnm,FADE_MAIN_BG,16*PGAPP_PALIDX_M,16*PGAPP_PALNUM_M,16,0x0000);
	SoftFadePfd(wk->sys->palAnm,FADE_MAIN_OBJ,16*PGAPPOAM_PALIDX_M,16*PGAPPOAM_PALNUM_M,16,0x0000);
	PaletteFadeTrans( wk->sys->palAnm );
	PaletteTrans_AutoSet(wk->sys->palAnm,FALSE);

	//ハンドル閉じる
	ArchiveDataHandleClose( handle );
}

/**
 *	@brief	BmpWin初期化
 */
static void pgradio_BmpWinAdd(PGRADIO_SYS_WORK* wk)
{
	int i;

	static const struct{
		u8 frm,px,py,sx,sy,pal;
		u16	cgx;
	}windat[] = {
	 { BMPL_PROG_FRM,BMPL_PROG_PX,BMPL_PROG_PY,BMPL_PROG_SX,BMPL_PROG_SY,
	   BMPL_PROG_PAL,BMPL_PROG_CGX},
	 { BMPL_DJ_FRM,BMPL_DJ_PX,BMPL_DJ_PY,BMPL_DJ_SX,BMPL_DJ_SY,
	   BMPL_DJ_PAL,BMPL_DJ_CGX},
	 { BMPL_TITLE_FRM,BMPL_TITLE_PX,BMPL_TITLE_PY,BMPL_TITLE_SX,BMPL_TITLE_SY,
	   BMPL_TITLE_PAL,BMPL_TITLE_CGX},
	};
	for(i = 0;i < WIN_MAX;i++){
		GF_BGL_BmpWinAdd(
			wk->sys->bgl, &wk->win[i], windat[i].frm,
			windat[i].px, windat[i].py, windat[i].sx, windat[i].sy, windat[i].pal, windat[i].cgx );
		GF_BGL_BmpWinDataFill(&(wk->win[i]),FBMP_COL_NULL);
	}

	{
#if 0
		u8 is_kanto = 0;

		if(PGFrame_GetLocalArea(wk->sys) != PGLOCAL_JOHTO){
			is_kanto = 1;
		}
#endif
		wk->pRadioSys = PMRadio_Init(wk->sys->save,
			wk->sys->param->player_zone,wk->sys->param->field_zone,
			ZoneData_IsKanto(wk->sys->param->player_zone),
			&(wk->win[WIN_PROG]),&(wk->win[WIN_TITLE]),&(wk->win[WIN_DJ]),
			GF_PRINTCOLOR_MAKE(1,2,0),wk->heapID);
	}
}

/*
 *	@brief	BmpWin開放
 */
static void pgradio_BmpWinDel(PGRADIO_SYS_WORK* wk)
{
	int i = 0;

	PMRadio_Release(wk->pRadioSys);

	for(i = 0;i < WIN_MAX;i++){
		GF_BGL_BmpWinOff(&wk->win[i]);
		GF_BGL_BmpWinDel(&wk->win[i]);
	}
}


/**
 *	@brief	ラジオのアクターリソース初期化
 */
static void pgradio_ActResInit(PGRADIO_SYS_WORK* wk)
{
	//リソース確保
	PGear_ActorResInit(wk->sys,PGAPP_MODE_RADIO);
}

/**
 *	@brief	ラジオのアクターリソース開放
 */
static void pgradio_ActResRelease(PGRADIO_SYS_WORK* wk)
{
	//リソース開放
	PGear_ActorResRelease(wk->sys);
}

/**
 *	@brief	ノーマルOBJの作成
 */
static void pgradio_MakeActor(PGRADIO_SYS_WORK* wk)
{
	int i;
	u16	idx;

	static const TCATS_OBJECT_ADD_PARAM	ActAddParam[] =
	{
		{	// カーソル
			RESACT_ROAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_CLU, 1, PGSYSOAM_PALNUM_M+1, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// カーソル
			RESACT_ROAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_CLD, 1, PGSYSOAM_PALNUM_M+1, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// カーソル
			RESACT_ROAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_CRU, 1, PGSYSOAM_PALNUM_M+1, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// カーソル
			RESACT_ROAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_CRD, 1, PGSYSOAM_PALNUM_M+1, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// 選局マーク
			RESACT_ROAM,	//ID
			128, 128, 0,	//x,y,z
			ANM_H_SEL, 1, PGSYSOAM_PALNUM_M+0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
	};
	for(i = 0;i < RACT_MAX;i++){
		wk->pAct[i] = CATS_ObjectAdd( wk->sys->pActSys,wk->sys->pActRes,&ActAddParam[i]);
		CATS_ObjectBGPriSet(wk->pAct[i],1);
		CLACT_SetDrawFlag(wk->pAct[i], FALSE);
		CLACT_SetAnmFlag(wk->pAct[i], TRUE);
	}
	CATS_ObjectBGPriSet(wk->pAct[RACT_SEL],3);
	CLACT_SetDrawFlag(wk->pAct[RACT_SEL],TRUE);
	CATS_ObjectPosSet(wk->pAct[RACT_SEL],wk->x,wk->y);
}

/**
 *	@brief	ノーマルOBJの開放
 */
static void pgradio_DelActor(PGRADIO_SYS_WORK* wk)
{
	int i;
	for(i = 0;i < RACT_MAX;i++){
		CATS_ObjectDel(wk->pAct[i]);
	}
}

/*
 *	@brief	初期画面描画
 */
static void pgradio_IniDraw(PGRADIO_SYS_WORK* wk)
{
	//コントロールモードによって、描画状態を変更
	if(wk->sys->control == PGCONT_SYS){
		CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,PGKM_SYS_PARAM,TRUE);
		CursorMvMan_SetCurrent(wk->sys->curMan,PGKM_SYS_PARAM,
				PGFrame_GetSCurModePosNo(wk->sys));
	}else{
		CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,PGKM_SYS_PARAM,FALSE);
	}
}
